<template>
	<a-table
		:class="className"
		:columns="curColumns"
		:dataSource="items"
		row-key="srfkey"
		:sticky="items.length > 0"
		:custom-row="customRow"
		:show-header="showHeader"
		:row-class-name="rowClassName"
		table-layout="fixed"
		:scroll="scrollOptions"
		:loading="loading"
		:bordered="true"
		:row-selection="
			singleSelect || localMode || curColumns.length == 0 ? false : rowSelection
		"
		:custom-header-row="customHeaderRow"
		:pagination="paging ? initPaging(props) : false"
		@change="handleGridChange"
		@resize-column="handleResizeColumn"
	>
		<template #headerCell="{ title, column }">
			<template v-if="column?.codeName === '$localactioncolumn'">
				<slot name="GridAdd" :column="column" :actions="{ handleAdd }">
					<AppButton
						type="primary"
						class="repeater-add--style2"
						size="small"
						shape="circle"
						:isDebounce="false"
						@click="handleAdd"
					>
						<template #icon>
							<PlusOutlined />
						</template>
					</AppButton>
				</slot>
			</template>
			<template v-else>
				<slot
					v-if="hasSlot(`${column?.codeName}Header`)"
					:title="title"
					:column="column"
					:name="`${column?.codeName}Header`"
				></slot>
				<slot
					name="GridHeader"
					:title="title"
					:column="column"
					v-else-if="hasSlot('GridHeader')"
				></slot>
				<AppGridColumnHeader
					v-else
					:column="column"
					:context="context"
					:viewParams="viewParams"
				/>
			</template>
		</template>
		<template #customFilterDropdown="{ column }">
			<slot
				name="GridFilterDropdown"
				:column="column"
				:actions="{ handleComponentAction }"
			>
				<AppGridColumnFilter @component-action="handleComponentAction">
					<template #default="{ handleComponentAction, value }">
						<slot
							v-if="hasSlot(column?.filterName)"
							:name="column?.filterName"
							:value="value"
							:handleComponentAction="handleComponentAction"
						/>
					</template>
				</AppGridColumnFilter>
			</slot>
		</template>
		<template #customFilterIcon="{ column }">
			<slot name="GridFilterIcon" :column="column">
				<AppSpan
					class="column-filter-tip"
					:codeListTag="column?.filterCodeListTag"
					:codeListType="column?.filterCodeListType"
					:value="columnFilter[column?.filterName]"
				></AppSpan>
				<SearchOutlined />
			</slot>
		</template>
		<template #bodyCell="{ column, text, record, index }">
			<template v-if="column?.codeName === '$localactioncolumn'">
				<slot name="GridRemove" :column="column" :actions="{ handleRemove }">
					<AppButton
						type="error"
						class="repeater-remove--style2"
						size="small"
						shape="circle"
						:isDebounce="false"
						@click="handleRemove(record, index)"
					>
						<template #icon>
							<DeleteOutlined />
						</template>
					</AppButton>
					<span class="row-index">{{ index + 1 }}</span>
				</slot>
			</template>
			<template v-else>
				<slot
					v-if="hasSlot(column?.codeName)"
					:text="text"
					:column="column"
					:record="record"
					:index="index"
					:name="column.codeName"
				/>
				<slot
					v-else-if="hasSlot('GridBody')"
					:text="text"
					:column="column"
					:record="record"
					:index="index"
					name="GridBody"
				>
				</slot>
				<AppGridColumn
					v-else
					:text="text"
					:column="column"
					:record="record"
					:index="index"
					:context="context"
					:viewParams="viewParams"
					@handle-action="
						(detail, event) => handleAction(detail, record, event)
					"
				/>
			</template>
		</template>
		<template #emptyText>
			<slot name="GridEmptyText">
				<AppEmptyDataTip :emptyText="emptyText"></AppEmptyDataTip>
			</slot>
		</template>
		<template #summary v-if="enableAgg">
			<slot name="GridEmptySummary" :aggData="aggData" :columns="curColumns">
				<a-table-summary fixed>
					<a-table-summary-row>
						<a-table-summary-cell></a-table-summary-cell>
						<a-table-summary-cell
							v-for="column in curColumns"
							:key="column.dataItemName"
						>
							{{ aggData[column.dataItemName] }}
						</a-table-summary-cell>
					</a-table-summary-row>
				</a-table-summary>
			</slot>
		</template>
		<template #footer v-if="enableColumnShowChange">
			<slot
				name="GridEmptyShowChange"
				:columns="curColumns"
				:actions="{ handleColumnShowChange }"
			>
				<div class="app-control-grid__column-show-change">
					<AppGridColumnShowChange
						:columns="columnModel"
						@column-show-change="handleColumnShowChange"
					></AppGridColumnShowChange>
				</div>
			</slot>
		</template>
	</a-table>
</template>
<script setup lang="ts">
import { gridProps, initPaging, resizeColumn } from './grid';
import AppGridColumn from './components/grid-column.vue';
import AppGridColumnHeader from './components/grid-column-header.vue';
import AppGridColumnShowChange from './components/grid-column-show-change.vue';
import AppGridColumnFilter from './components/grid-column-filter.vue';
import AppEmptyDataTip from '@/components/common/empty-data-tip/src/empty-data-tip.vue';
import {
	SearchOutlined,
	PlusOutlined,
	DeleteOutlined,
} from '@ant-design/icons-vue';
import { IParam, isEmptyObj, IEvent } from '@/core';
const props = defineProps(gridProps);
const emit = defineEmits<{
	(name: 'selectionChange', selections: IParam[]): void;
	(name: 'rowClick', row: IParam, event: MouseEvent): void;
	(name: 'rowDbClick', row: IParam, event: MouseEvent): void;
	(name: 'pageSizeChange', size: number): void;
	(name: 'pageChange', currentPage: number): void;
	(name: 'paginationChange', page: { page: number; size: number }): void;
	(name: 'sortChange', field: string, dir: 'asc' | 'desc' | ''): void;
	(name: 'actionClick', logic: IParam, data: IParam, event: MouseEvent): void;
	(name: 'addItem'): void;
	(name: 'removeItem', row: IParam, index: number): void;
	(name: 'column-filter-change', data: IParam): void;
}>();
// 自定义表格头
const customHeaderRow = (columns: IParam[], rowIndex: number) => {
	if (!props.customCallBack) {
		return;
	}
	const style = props.customCallBack('calcheaderrowstyle', {
		columns,
		rowIndex,
	});
	return { style };
};
// 自定义表格单元格
const customCell = (row: IParam, rowIndex: number, column: IParam) => {
	if (!props.customCallBack) {
		return;
	}
	const style = props.customCallBack('calccellstyle', {
		row,
		column,
		rowIndex,
	});
	return { style };
};
// 自定义表格头单元格
const customHeaderCell = (column: IParam) => {
	if (!props.customCallBack) {
		return;
	}
	const style = props.customCallBack('calcheadercellstyle', { column });
	return { style };
};
// 自定义表格行样式
const customRowStyle = (row: IParam, rowIndex: number) => {
	if (!props.customCallBack) {
		return;
	}
	const style = props.customCallBack('calcrowstyle', { row, rowIndex });
	return { style };
};

const hasSlot = (name: string): boolean => {
	return !!useSlots()[name];
};

const selectedKeys = computed<string[]>(() => {
	return props.selections.map((select: IParam) => select.srfkey) || [];
});
// 列模型
const columnModel = ref<IParam[]>([]);
const computeResize = (columns: IParam[]): boolean => {
	return columns.some((column: IParam) => {
		if (column.minWidth) {
			return true;
		}
		if (
			Object.is(column.columnType, 'GROUPGRIDCOLUMN') &&
			column.children.length > 0
		) {
			return computeResize(column.children);
		} else {
			return false;
		}
	});
};

let hasResize: boolean = false;

const getLocalActionColumn = () => {
	return {
		align: 'center',
		codeName: '$localactioncolumn',
		width: 64,
		dataIndex: '$localactioncolumn',
		customCell: (record: IParam, rowIndex: number, column: IParam) => {
			return { class: 'localmode-remove-cell' };
		},
	};
};
watch(
	() => props.columns,
	() => {
		if (props.columns.length > 0) {
			columnModel.value.length = 0;
			hasResize = computeResize(props.columns);
			let hasUaColumn: boolean = false;
			props.columns.forEach((column: IParam) => {
				column.customCell = customCell;
				column.customHeaderCell = customHeaderCell;
				columnModel.value.push(column);
				if (Object.is(column.columnType, 'UAGRIDCOLUMN')) {
					hasUaColumn = true;
				}
			});
			if (!hasResize) {
				if (hasUaColumn) {
					columnModel.value.splice(
						columnModel.value.length - 1,
						0,
						resizeColumn
					);
				} else {
					columnModel.value.push(resizeColumn);
				}
			}
		}
	},
	{ immediate: true }
);
// 当前运行时列
const curColumns = computed(() => {
	const columns = columnModel.value.filter((model: IParam) => model.show);
	if (props.localMode) {
		columns.unshift(getLocalActionColumn());
	}
	return columns;
});
//  设置定时器防抖
let timer: any = null;
//  表格行选择配置项
const rowSelection: any = {
	columnWidth: 64,
	selectedRowKeys: selectedKeys,
	checkStrictly: false,
	onSelect: (record: IParam, selected: boolean, selectedRows: IParam[]) => {
		const selections: IParam[] = [];
		if (props.singleSelect) {
			if (selected) {
				selections.push(record);
			}
		} else {
			selections.push(...selectedRows);
		}
		emit('selectionChange', selections);
	},
	onSelectAll: (selected: boolean, selectedRows: IParam[]) => {
		emit('selectionChange', selectedRows);
	},
};
//  行配置项
const customRow = (record: IParam, index: number) => {
	// 行界面逻辑
	const customRow = {
		onClick: (event: MouseEvent) => {
			//  开启行编辑不响应单击事件
			if (props.enableRowEdit || record.isGroupItem) {
				return;
			}
			clearTimeout(timer);
			timer = setTimeout(() => {
				emit('rowClick', record, event);
			}, 200);
		},
		onDblclick: (event: MouseEvent) => {
			//  开启行编辑不响应双击事件
			if (props.enableRowEdit || record.isGroupItem) {
				return;
			}
			clearTimeout(timer);
			emit('rowDbClick', record, event);
		},
	};
	// 逻辑样式
	const style = customRowStyle(record, index);
	Object.assign(customRow, style);
	return customRow;
};
const className = computed<any>(() => {
	const classes = {
		'app-control-grid--custom-resize': !hasResize,
	};
	return classes;
});
const rowClassName = (record: IParam, index: number) => {
	let classNames: string = '';
	if (props.rowClassNameLogic) {
		classNames += props.rowClassNameLogic(record);
	}
	if (index % 2 === 1) {
		classNames += 'ant-table-row-striped';
	}
	if (selectedKeys.value) {
		const selected = selectedKeys.value.includes(record.srfkey);
		if (selected) {
			classNames += ' ant-table-row-selected';
		}
	}
	return classNames;
};
const limit = ref(
	props.paging && props.paging.defaultPageSize
		? props.paging.defaultPageSize
		: 20
);
const currentPage = ref(props.current ? props.current : 1);
const currentSort = ref({ sortField: '', sortDir: 'ascend' });

//  表格滚动配置项
const scrollOptions = ref({
	scrollToFirstRowOnChange: true,
	x: 'max-content',
	y: '100%',
});

//  处理切换列宽
const handleResizeColumn = (width: number, col: IParam) => {
	col.width = width;
};

const handleGridChange = (
	pagination: IParam,
	filters: IParam,
	sorter: IParam,
	data: IParam
) => {
	//  分页变化
	if (
		!isEmptyObj(pagination) &&
		(pagination.current !== currentPage.value ||
			pagination.pageSize !== limit.value)
	) {
		if (pagination.current !== currentPage.value) {
			currentPage.value = pagination.current;
			emit('pageChange', currentPage.value);
		}
		if (pagination.pageSize !== limit.value) {
			limit.value = pagination.pageSize;
			emit('pageSizeChange', limit.value);
		}
		emit('paginationChange', { page: currentPage.value, size: limit.value });
		return;
	}
	//  排序变化
	if (sorter) {
		const { field, order } = sorter;
		if (
			field !== currentSort.value.sortField ||
			order !== currentSort.value.sortDir
		) {
			currentSort.value = { sortDir: order, sortField: field };
			emit(
				'sortChange',
				field,
				order === 'ascend' ? 'asc' : order === 'descend' ? 'desc' : ''
			);
		}
	}
};

onMounted(() => {
	computeRisizeColumn();
});
// 修复ant表格组件在设置min-width 无width时 分辨率过小 列丢失
const computeRisizeColumn = () => {
	if (!hasResize) {
		return;
	}
	const instance = getCurrentInstance();
	if (instance) {
		const el = instance.vnode.el;
		if (!el) {
			return;
		}
		const colgroup: any[] = el.getElementsByTagName('colgroup');
		if (colgroup.length > 0) {
			let index = props.singleSelect ? 0 : 1;
			curColumns.value.forEach((column: IParam) => {
				if (column.minWidth) {
					const col = colgroup[1].children[index];
					if (col) {
						col.style = `min-width:${column.minWidth}px`;
					}
				}
				if (
					Object.is(column.columnType, 'GROUPGRIDCOLUMN') &&
					column.children.length > 0
				) {
					column.children.forEach((item: IParam) => {
						if (item.minWidth) {
							const col = colgroup[1].children[index];
							if (col) {
								col.style = `min-width:${item.minWidth}px`;
							}
						}
						index++;
					});
				} else {
					index++;
				}
			});
		}
	}
};
const handleAction = (detail: IParam, data: IParam, event: MouseEvent) => {
	emit('actionClick', detail.logic, data, event);
};

//  处理列显示状态变化（后续逻辑）
const handleColumnShowChange = (codeName: string, checked: boolean) => {};

const handleComponentAction = ({ name, action, data }: IEvent<string>) => {
	switch (action) {
		case 'column-filter-change':
			handleColumnFilterChange(name, data);
			break;
	}
};
//	处理列过滤值变化
const handleColumnFilterChange = (name: string, value: any) => {
	emit('column-filter-change', { [name]: value });
};
//	添加数据
const handleAdd = () => {
	emit('addItem');
};

//	删除数据
const handleRemove = (item: IParam, index: number) => {
	emit('removeItem', item, index);
};
</script>
